<template>
	<div class="default-main">

		<el-divider id="smallPrint-divider" content-position="center">
			<el-space>
				<el-select v-model="params.classificationId" class="filter-select" size="default" @change="handleSearch">
					<el-option :value="0" label="所有类别"></el-option>
					<el-option v-for="classification in classificationList" :label="classification.name" :value="classification.id!"></el-option>
				</el-select>
				<el-select v-model="params.minRate" class="filter-select" size="default" @change="handleSearch">
					<el-option :value="0" label="所有评分"></el-option>
					<el-option :value="5" label="5星及以上"></el-option>
					<el-option :value="4" label="4星及以上"></el-option>
					<el-option :value="3" label="3星及以上"></el-option>
					<el-option :value="2" label="2星及以上"></el-option>
					<el-option :value="1" label="1星及以上"></el-option>
				</el-select>
				<el-select v-model="params.order" class="filter-select" size="default" @change="handleSearch">
					<el-option :value="1" label="最多下载"></el-option>
					<el-option :value="2" label="评分最高"></el-option>
					<el-option :value="3" label="最近上传"></el-option>
					<el-option :value="4" label="最近更新"></el-option>
					<el-option :value="5" label="按名称排序"></el-option>
				</el-select>
				<el-input v-model="params.blueprintName_like" class="filter-input" clearable placeholder="蓝图名称" @keyup.enter="handleSearch"></el-input>
				<el-select v-model="params.authorId_eq" class="filter-input" clearable filterable placeholder="作者" @change="handleSearch">
					<el-option v-for="author in authorList" :label="author.authorName" :value="author.id!"></el-option>
				</el-select>
				<el-button icon="el-icon-Search" type="primary" @click="handleSearch">搜索</el-button>
				<el-button icon="el-icon-Refresh" type="primary" @click="refresh">重置</el-button>
				<el-button v-if="isAdmin()" icon="el-icon-Plus" type="primary" @click="toAdd">新增</el-button>
			</el-space>
		</el-divider>

		<div v-loading="tableLoading" :style="{height: (dataAreaHeight ?? 800) + 'px'}">
			<el-scrollbar>
				<el-row v-if="!tableLoading && blueprintTableData.length > 0" :gutter="50" style="margin-right: 0">
					<el-col v-for="blueprintVo in blueprintTableData" :key="blueprintVo.id" :span="6" style="margin-top: 50px;min-width: 250px">
						<el-card body-class="card-body" style="height: 100%">
							<el-image :src="blueprintVo.images![0]" fit="cover" lazy style="width: 100%;height: 400px;cursor: pointer" @click="toView(blueprintVo)">
								<template #error>
									<el-image :src="getImage('others/image-error.png')" fit="cover" lazy style="width: 100%;height: 400px;cursor: pointer"
									          @click="toView(blueprintVo)"></el-image>
								</template>
							</el-image>
							<div class="cus-center-column" style="padding-bottom: 15px">
								<el-rate v-model="blueprintVo.rate" disabled></el-rate>
								<el-link :underline="false" style="text-align: center;font-weight: bold;font-size: 1.2rem" @click="toView(blueprintVo)">{{
										blueprintVo.blueprintName
									}}
								</el-link>
								<div v-if="isAdmin()" class="cus-center" style="margin-top: 15px">
									<el-button icon="el-icon-Edit" size="small" type="primary" @click="toUpdate(blueprintVo)">编辑</el-button>
									<el-popconfirm :hide-after="0" :title="`删除该蓝图（${blueprintVo.blueprintName}）？`" confirm-button-type="danger" width="auto"
									               @confirm="deleteBlueprint(blueprintVo)">
										<template #reference>
											<el-button v-auth="'g-blueprint:deleteBlueprint'" icon="el-icon-Delete" size="small" type="danger">删除</el-button>
										</template>
									</el-popconfirm>
								</div>
							</div>
						</el-card>
					</el-col>
				</el-row>
				<el-empty v-if="!tableLoading && blueprintTableData.length === 0"></el-empty>
			</el-scrollbar>
		</div>

		<cus-pagination id="smallPrint-pagination" ref="pageRef" v-model="blueprintTableData" v-model:loading="tableLoading" :page-sizes="[4,8,12,16,20]"
		                :pageSize="12"
		                :params="params" url="/game/g-blueprint/readOnly/searchBlueprintByPage"/>

		<!-- 对话框（新增、修改） -->
		<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="true" :title="dialogTitle" append-to-body center class="cus-dialog"
		           destroy-on-close draggable width="50%">
			<el-form ref="editFormRef" :model="blueprintVo" :rules="rules" label-width="auto">
				<el-form-item label="蓝图名称" prop="blueprintName">
					<el-input v-model="blueprintVo.blueprintName" clearable/>
				</el-form-item>
				<el-form-item label="图片" prop="images">
					<el-row v-for="(image, index) in blueprintVo.images" :gutter="10" class="w100">
						<el-col :span="22">
							<el-input v-model="blueprintVo.images![index]"/>
						</el-col>
						<el-col :span="2">
							<el-button plain size="small" type="danger" @click="() => blueprintVo.images?.splice(index, 1)">-</el-button>
						</el-col>
					</el-row>
					<el-button plain size="small" style="margin-top: 5px" type="primary" @click="() => blueprintVo.images?.push('')">+</el-button>
				</el-form-item>
				<!-- 描述富文本编辑器 -->
				<div id="editor"></div>
				<el-form-item label="类别" prop="rate" style="margin-top: 20px">
					<el-select v-model="blueprintVo.classificationIdList" :max-collapse-tags="5" clearable collapse-tags filterable multiple>
						<el-option v-for="classification in classificationList" :label="classification.name" :value="classification.id!"></el-option>
					</el-select>
				</el-form-item>
				<el-row :gutter="20" justify="space-between">
					<el-col :span="12">
						<el-form-item label="项目计数" prop="itemCount">
							<el-input-number v-model="blueprintVo.itemCount" :min="0" :step="1" class="w100" controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="作者" prop="authorId">
							<el-select v-model="blueprintVo.authorId" clearable filterable>
								<el-option v-for="author in authorList" :label="author.authorName" :value="author.id!"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="space-between">
					<el-col :span="12">
						<el-form-item label="游戏版本" prop="gameVersion">
							<el-input-number v-model="blueprintVo.gameVersion" :min="1" :step="1" class="w100" controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="评分" prop="rate">
							<el-rate v-model="blueprintVo.rate"/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="space-between">
					<el-col :span="12">
						<el-form-item label="蓝图下载" prop="downloadUrl">
							<el-input v-model="blueprintVo.downloadUrl"/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="配置文件下载" prop="configDownloadUrl">
							<el-input v-model="blueprintVo.configDownloadUrl"/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="space-between">
					<el-col :span="12">
						<el-form-item label="文件大小" prop="fileSize">
							<el-input v-model="blueprintVo.fileSize" :min="0" class="w100" controls-position="right" type="number">
								<template #append>
									<el-form-item prop="fileSizeUnit">
										<business-code-select v-model="blueprintVo.fileSizeUnit" :clearable="false" :filterable="false" class="append-select"
										                      code-type="fileSizeUnit"></business-code-select>
									</el-form-item>
								</template>
							</el-input>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="下载次数" prop="downloadCount">
							<el-input-number v-model="blueprintVo.downloadCount" :min="0" :step="1" class="w100" controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="space-between">
					<el-col :span="12">
						<el-form-item label="图标图片" prop="iconImage">
							<el-input v-model="blueprintVo.iconImage"/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="图标背景色" prop="iconImageBackground">
							<el-input v-model="blueprintVo.iconImageBackground"/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="space-between">
					<el-col :span="12">
						<el-form-item label="上传时间" prop="blueprintCreateTime">
							<el-input v-model="blueprintVo.blueprintCreateTime"/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="更新时间" prop="blueprintUpdateTime">
							<el-input v-model="blueprintVo.blueprintUpdateTime"/>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<template #footer>
				<el-button v-auth="'g-blueprint:saveBlueprint'" icon="el-icon-CircleCheck" type="primary" @click="save">
					保存
				</el-button>
				<el-button icon="el-icon-CircleClose" type="warning" @click="dialogVisible = false">
					取消
				</el-button>
			</template>
		</el-dialog>

		<!-- 对话框（查看） -->
		<el-dialog v-model="viewDialogVisible" :close-on-click-modal="true" :close-on-press-escape="true" :title="viewDialogTitle" append-to-body center
		           class="cus-dialog" destroy-on-close draggable width="90%">
			<!-- 图片 -->
			<el-carousel v-if="blueprintVo.images && blueprintVo.images.length > 0" arrow="always" height="auto" indicator-position="outside" motion-blur>
				<el-carousel-item v-for="image in blueprintVo.images" :key="image" style="height: 500px">
					<el-image :src="image" fit="contain" style="height: 100%; width: 100%">
						<template #error>
							<el-image :src="getImage('others/image-error.png')" fit="contain" lazy style="width: 100%;height: 100%"></el-image>
						</template>
					</el-image>
				</el-carousel-item>
			</el-carousel>
			<el-container>
				<!-- 蓝图图标 -->
				<el-aside v-if="blueprintVo.iconImage" width="400">
					<div class="image-container">
						<el-image :src="getImage('others/TXUI_BlueprintIconBG_Mask.png')" :style="{background: blueprintVo.iconImageBackground}" class="background-image"
						          fit="cover"></el-image>
						<el-image :src="blueprintVo.iconImage" class="foreground-image" fit="contain">
							<template #error>
								<el-image :src="getImage('others/image-error.png')" class="foreground-image" fit="contain"></el-image>
							</template>
						</el-image>
					</div>
				</el-aside>
				<!-- 蓝图详情 -->
				<el-main>
					<ckeditor
							v-model="editorData"
							:config="editorConfig"
							:editor="editor"
							disabled
					/>
					<el-descriptions :column="1" border style="margin-top: 20px">
						<el-descriptions-item align="center" label="项目计数" label-align="center">
							{{ blueprintVo.itemCount }}
						</el-descriptions-item>
						<el-descriptions-item align="center" label="类别" label-align="center">
							<el-space>
								<el-tag v-for="classificationName in getClassificationNames(blueprintVo.classificationIdList)" effect="plain">{{ classificationName }}</el-tag>
							</el-space>
						</el-descriptions-item>
					</el-descriptions>
					<el-descriptions :column="1" border style="margin-top: 20px">
						<el-descriptions-item align="center" label="评分" label-align="center">
							<el-rate v-model="blueprintVo.rate" disabled></el-rate>
						</el-descriptions-item>
						<el-descriptions-item align="center" label="游戏版本" label-align="center">
							{{ blueprintVo.gameVersion }}
						</el-descriptions-item>
						<el-descriptions-item align="center" label="作者" label-align="center">
							{{ getAuthorName(blueprintVo.authorId!) }}
						</el-descriptions-item>
					</el-descriptions>
					<el-descriptions :column="1" border style="margin-top: 20px">
						<el-descriptions-item align="center" label="下载" label-align="center">
							<el-button type="primary" @click="downloadBlueprint">下载&nbsp;SBP</el-button>
							<el-tooltip v-if="blueprintVo.configDownloadUrl" :hide-after="0" content="需要保留蓝图的描述、图标、颜色时才需要" placement="top">
								<el-button type="primary" @click="downloadBlueprintConfig">下载&nbsp;SBP&nbsp;配置</el-button>
							</el-tooltip>
						</el-descriptions-item>
						<el-descriptions-item align="center" label="文件大小" label-align="center">
							{{ blueprintVo.fileSize }}&nbsp;{{ getBusinessCodeName('fileSizeUnit', blueprintVo.fileSizeUnit!) }}
						</el-descriptions-item>
						<el-descriptions-item align="center" label="下载次数" label-align="center">
							{{ blueprintVo.downloadCount }}
						</el-descriptions-item>
					</el-descriptions>
					<el-descriptions :column="1" border style="margin-top: 20px">
						<el-descriptions-item align="center" label="上传时间" label-align="center">
							{{ blueprintVo.blueprintCreateTime }}
						</el-descriptions-item>
						<el-descriptions-item align="center" label="更新时间" label-align="center">
							{{ blueprintVo.blueprintUpdateTime }}
						</el-descriptions-item>
					</el-descriptions>
				</el-main>
			</el-container>
			<template #footer>
				<el-button icon="el-icon-CircleClose" type="warning" @click="viewDialogVisible = false">
					关闭
				</el-button>
			</template>
		</el-dialog>

	</div>
</template>

<script lang="ts" name="SmallBlueprint" setup>
import {isAdmin} from '@/utils/authUtil'
import CusPagination from '@/components/cus-pagination.vue'
import {nextTick, onActivated, onMounted, reactive, ref} from 'vue'
import {deleteBlueprintApi, getAllBlueprintAuthorApi, getAllBlueprintClassificationApi, saveBlueprintApi} from '@/api/gameData/blueprint.api'
import {focusFormErrorElement, getBusinessCodeName, getImage, messageSuccess} from '@/utils/commonUtil'
import {calcMaxHeight} from '@/utils/layoutUtil'
import {debounce, type DebouncedFunc} from 'lodash-es'
import {useEventListener} from '@vueuse/core'
import {onBeforeRouteLeave} from 'vue-router'
import type {FormRules} from 'element-plus'
import {Bold, ClassicEditor, type EditorConfig, Essentials, Font, Italic, Mention, Paragraph, Undo} from 'ckeditor5'
import coreTranslations from 'ckeditor5/translations/zh-cn.js'
import {useI18n} from 'vue-i18n'
import BusinessCodeSelect from '@/components/business-code-select.vue'

const pageRef = ref()
const editFormRef = ref()

const {t} = useI18n()

const blueprintTableData = ref<BlueprintVo[]>([])
const tableLoading = ref(false)

const classificationList = ref<GClassification[]>([])

const authorList = ref<GBlueprintAuthor[]>([])

const params = reactive({
	isMega_eq: 0,
	minRate: 0,
	classificationId: 0,
	order: 3,
	blueprintName_like: undefined,
	authorId_eq: undefined
})

const dataAreaHeight = ref<number>()

const viewDialogVisible = ref(false)
const viewDialogTitle = ref<string>()

const dialogVisible = ref(false)
const dialogTitle = ref<string>()

const editor = ClassicEditor
const editorData = ref<string>()
const editorConfig: EditorConfig = {
	plugins: [Bold, Essentials, Italic, Mention, Paragraph, Undo],
	toolbar: {
		items: [
			// 'undo', 'redo', 'selectAll',
			// '|', 'bold', 'italic',
			// '|', 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor',
			// '|', 'accessibilityHelp'
		],
		shouldNotGroupWhenFull: false,
	},
	menuBar: {
		isVisible: false
	},
	translations: [
		coreTranslations
	],
	language: {
		ui: 'zh-cn',
		content: 'zh-cn'
	}
}

const blueprintVo = reactive<BlueprintVo>({
	id: undefined,
	blueprintName: undefined,
	description: undefined,
	sort: 0,
	isMega: 0,
	itemCount: undefined,
	coordinate: undefined,
	isOriginalLocationOnly: undefined,
	rate: undefined,
	gameVersion: undefined,
	authorId: undefined,
	downloadUrl: undefined,
	configDownloadUrl: undefined,
	downloadCount: 0,
	fileSize: undefined,
	fileSizeUnit: undefined, // 文件大小单位：	1-KB	2-MB	3-GB
	blueprintCreateTime: undefined,
	blueprintUpdateTime: undefined,
	images: [],
	iconImage: undefined,
	iconImageBackground: undefined,
	operator: undefined,
	createTime: undefined,
	updateTime: undefined,
	classificationIdList: []
})

const resetBlueprintVo = () => {
	blueprintVo.id = undefined
	blueprintVo.blueprintName = undefined
	blueprintVo.description = undefined
	blueprintVo.sort = 0
	blueprintVo.isMega = 0
	blueprintVo.itemCount = undefined
	blueprintVo.coordinate = undefined
	blueprintVo.isOriginalLocationOnly = undefined
	blueprintVo.rate = undefined
	blueprintVo.gameVersion = undefined
	blueprintVo.authorId = undefined
	blueprintVo.downloadUrl = undefined
	blueprintVo.configDownloadUrl = undefined
	blueprintVo.downloadCount = 0
	blueprintVo.fileSize = undefined
	blueprintVo.fileSizeUnit = undefined
	blueprintVo.blueprintCreateTime = undefined
	blueprintVo.blueprintUpdateTime = undefined
	blueprintVo.images = []
	blueprintVo.iconImage = undefined
	blueprintVo.iconImageBackground = undefined
	blueprintVo.operator = undefined
	blueprintVo.createTime = undefined
	blueprintVo.updateTime = undefined
	blueprintVo.classificationIdList = []
}

const rules = reactive<FormRules>({
	blueprintName: [
		{required: true, message: '请输入蓝图名称', trigger: 'change'}
	],
	isMega: [
		{required: true, message: '请选择是否是巨型蓝图', trigger: 'change'}
	],
	gameVersion: [
		{required: true, message: '请输入游戏版本', trigger: 'change'}
	],
	downloadUrl: [
		{required: true, message: '请输入下载链接', trigger: 'change'}
	],
	downloadCount: [
		{required: true, message: '请输入下载次数', trigger: 'change'}
	],
	fileSize: [
		{required: true, message: '请输入文件大小', trigger: 'change'}
	],
	fileSizeUnit: [
		{required: true, message: '请选择文件大小单位', trigger: 'change'}
	],
	emailValid: [
		{required: true, message: '请选择邮箱激活状态', trigger: 'change'}
	],
	blueprintCreateTime: [
		{required: true, message: '请输入蓝图创建时间', trigger: 'change'}
	],
	blueprintUpdateTime: [
		{required: true, message: '请输入蓝图更新时间', trigger: 'change'}
	]
})

const toView = (row: BlueprintVo) => {
	resetBlueprintVo()
	Object.assign(blueprintVo, JSON.parse(JSON.stringify(row)))
	viewDialogTitle.value = '蓝图：' + blueprintVo.blueprintName
	editorData.value = blueprintVo.description
	viewDialogVisible.value = true
}

const getClassificationNames = (classificationIdList: number[]): string[] => {
	const classificationNames: string[] = []
	if (!classificationIdList || classificationIdList.length === 0) {
		return classificationNames
	}
	for (const classificationId of classificationIdList) {
		const classification = classificationList.value.find(item => item.id === classificationId)
		if (classification) {
			classificationNames.push(classification.name!)
		}
	}
	return classificationNames
}

const getAuthorName = (authorId: number): string | undefined => {
	for (const author of authorList.value) {
		if (author.id === authorId) {
			return author.authorName
		}
	}
	return undefined
}

const downloadBlueprint = () => {
	window.open(blueprintVo.downloadUrl, '_blank')
}

const downloadBlueprintConfig = () => {
	window.open(blueprintVo.configDownloadUrl, '_blank')
}

const toUpdate = (row: BlueprintVo) => {
	resetBlueprintVo()
	Object.assign(blueprintVo, JSON.parse(JSON.stringify(row)))
	dialogTitle.value = '编辑蓝图：' + blueprintVo.blueprintName
	dialogVisible.value = true
	nextTick(() => {
		// 初始化富文本编辑器
		ClassicEditor.create(document.querySelector('#editor') as HTMLElement, {
			plugins: [Essentials, Bold, Italic, Font, Paragraph],
			toolbar: {
				items: [
					'undo', 'redo', 'selectAll',
					'|', 'bold', 'italic',
					'|', 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor',
					'|', 'accessibilityHelp'
				],
				shouldNotGroupWhenFull: false
			},
			menuBar: {
				isVisible: false
			},
			htmlEmbed: {},
			initialData: blueprintVo.description,
			translations: [
				coreTranslations
			],
			language: {
				ui: 'zh-cn',
				content: 'zh-cn'
			}
		}).then(editor => {
			// 监听编辑器内容变化，赋值给blueprint.description
			editor.model.document.on('change:data', () => {
				blueprintVo.description = editor.getData()
			})
		}).catch(error => {
			console.error(error)
		})
	})
}

const save = () => {
	editFormRef.value?.validate((isValid: boolean) => {
		if (isValid) {
			saveBlueprintApi(blueprintVo).then(() => {
				messageSuccess(t('successMessage.save'))
				dialogVisible.value = false
				handleSearch()
			})
		} else {
			focusFormErrorElement()
		}
	})
}

const deleteBlueprint = (row: BlueprintVo) => {
	deleteBlueprintApi(row.id!).then(() => {
		messageSuccess(t('successMessage.delete'))
		handleSearch()
	})
}

const calcDataAreaHeight: DebouncedFunc<() => typeof calcDataAreaHeight> = debounce(() => {
	dataAreaHeight.value = calcMaxHeight('#smallPrint-divider', '#smallPrint-pagination')
	return calcDataAreaHeight
}, 100, {
	leading: true,
	trailing: false,
	maxWait: 100
})

const resetParams = () => {
	params.isMega_eq = 0
	params.minRate = 0
	params.classificationId = 0
	params.order = 3
	params.blueprintName_like = undefined
	params.authorId_eq = undefined
}

const toAdd = () => {
	resetBlueprintVo()
	dialogTitle.value = '新增蓝图'
	dialogVisible.value = true
	nextTick(() => {
		// 初始化富文本编辑器
		ClassicEditor.create(document.querySelector('#editor') as HTMLElement, {
			plugins: [Essentials, Bold, Italic, Font, Paragraph],
			toolbar: {
				items: [
					'undo', 'redo', 'selectAll',
					'|', 'bold', 'italic',
					'|', 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor',
					'|', 'accessibilityHelp'
				],
				shouldNotGroupWhenFull: false
			},
			menuBar: {
				isVisible: false
			},
			htmlEmbed: {},
			initialData: blueprintVo.description,
			translations: [
				coreTranslations
			],
			language: {
				ui: 'zh-cn',
				content: 'zh-cn'
			}
		}).then(editor => {
			// 监听编辑器内容变化，赋值给blueprint.description
			editor.model.document.on('change:data', () => {
				blueprintVo.description = editor.getData()
			})
		}).catch(error => {
			console.error(error)
		})
	})
}

const handleSearch = () => {
	pageRef.value.reload()
}

const refresh = () => {
	resetParams()
	handleSearch()
}

const initClassificationOptions = () => {
	getAllBlueprintClassificationApi().then(response => {
		classificationList.value = response.data
	})
}

const initAuthorOptions = () => {
	getAllBlueprintAuthorApi().then(response => {
		authorList.value = response.data
	})
}

initClassificationOptions()
initAuthorOptions()

onMounted(() => {
	useEventListener(window, 'resize', calcDataAreaHeight()!)
})

// 该页面开启缓存且首次或后续进入时执行，刷新页面不执行
onActivated(() => {
	useEventListener(window, 'resize', calcDataAreaHeight()!)
})

onBeforeRouteLeave(() => {
	window.removeEventListener('resize', calcDataAreaHeight)
})

</script>

<style lang="scss" scoped>

:deep(.el-input-group__append, .el-input-group__prepend) {
	padding: 0;
}

.append-select {
	margin: 0;
	width: 100px;
}

:deep(.ck.ck-editor__main > .ck-editor__editable) {
	background: var(--cus-ck-color-base-background);
}

:deep(.ck.ck-toolbar) {
	background: var(--cus-ck-color-toolbar-background);
}

:deep(.card-body) {
	padding: 0;
	height: 100%;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	align-items: center;
}

.filter-select {
	width: 120px;
}

.filter-input {
	width: 400px;
}

.image-container {
	position: relative;
	width: 400px;
	height: 400px;
}

.background-image {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 1;
}

.foreground-image {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 80%;
	height: 80%;
	transform: translate(-50%, -50%);
	z-index: 2;
}

:deep(.el-descriptions__label.el-descriptions__cell.is-bordered-label) {
	width: 250px;
}

</style>
